package api

import (
	"github.com/gin-gonic/gin"
	"zhonghui/console/warehouse/dbx"
	"zhonghui/console/warehouse/dbx/db_zh_kernel"
	"zhonghui/console/warehouse/respx"

	"zhonghui/console/warehouse/modelx/model_zh_kernel"

	"zhonghui/console/service"
	"zhonghui/console/structs"
)

func (server *Server) GetPolicies(c *gin.Context) {
	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	if !service.CanDo(user.ID, "*:*") {
		respx.Alert(c, "没有权限")
		return
	}

	policies := make([]model_zh_kernel.ConsolePolicies, 0)
	if err := db_zh_kernel.Client().Where("code != 'AdminFullAccess'").Order("id desc").Find(&policies).Error; err != nil {
		respx.Alert(c, "查询策略列表失败")
		return
	}

	resp := make([]structs.GetPoliciesResp, 0)
	for _, policy := range policies {
		resp = append(resp, structs.GetPoliciesResp{
			Id:   policy.ID,
			Name: policy.Name,
			Code: policy.Code,
			Conf: policy.Conf,
		})
	}

	respx.Success(c, resp, nil)
}

func (server *Server) GetPermissions(c *gin.Context) {
	req := structs.GetPermissionsReq{}
	if err := c.ShouldBindQuery(&req); err != nil {
		respx.Bad(c, err)
		return
	}

	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	if !service.CanDo(user.ID, "*:*") {
		respx.Alert(c, "没有权限")
		return
	}

	// 查询用户的权限
	permissions := make([]model_zh_kernel.ConsolePermissions, 0)
	if err := db_zh_kernel.Client().Where("entity = ? and entity_id = ?", req.Entity, req.EntityId).Find(&permissions).Error; err != nil {
		respx.Alert(c, "查询权限列表错误")
	}

	// 遍历用户的权限
	policyIds := make([]int, 0)
	for _, permission := range permissions {
		policyIds = append(policyIds, int(permission.PolicyID))
	}

	// 查询这些策略列表
	policies := make([]model_zh_kernel.ConsolePolicies, 0)
	if err := db_zh_kernel.Client().Where("id in (?)", policyIds).Order("id desc").Find(&policies).Error; err != nil {
		respx.Alert(c, "查询策略列表失败")
		return
	}

	resp := make([]structs.GetPermissionResp, 0)
	for _, policy := range policies {
		resp = append(resp, structs.GetPermissionResp{
			Id:   policy.ID,
			Name: policy.Name,
			Code: policy.Code,
			Conf: policy.Conf,
		})
	}

	respx.Success(c, resp, nil)
}

func (server *Server) PutPermissions(c *gin.Context) {
	req := structs.PutPermissionsReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		respx.Bad(c, err)
		return
	}

	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	if !service.CanDo(user.ID, "*:*") {
		respx.Alert(c, "没有权限")
		return
	}

	// 超级管理员组不允许更改
	if req.Entity == "group" && req.EntityId == 1 {
		respx.Alert(c, "超级管理员组不允许更改")
	}

	// 查询策略列表
	policies := make([]model_zh_kernel.ConsolePolicies, 0)
	if err := db_zh_kernel.Client().Where("id in (?)", req.PolicyIds).Find(&policies).Error; err != nil {
		respx.Alert(c, "查询策略列表错误")
		return
	}

	// 检查授权对象
	switch req.Entity {
	case "manager":
		if err := db_zh_kernel.Client().Where("id = ?", req.EntityId).Take(&model_zh_kernel.ConsoleManager{}).Error; err != nil {
			respx.Alert(c, "无法找到被授权对象")
			return
		}
	case "group":
		if err := db_zh_kernel.Client().Where("id = ?", req.EntityId).Take(&model_zh_kernel.ConsoleGroups{}).Error; err != nil {
			respx.Alert(c, "无法找到被授权对象")
			return
		}
	default:
		respx.Alert(c, "授权对象错误")
		return
	}

	conn := dbx.NewTx(db_zh_kernel.Client().Begin())
	defer conn.End()

	// 清除旧授权
	if err := conn.Tx.Where("entity = ? and entity_id = ?", req.Entity, req.EntityId).Delete(model_zh_kernel.ConsolePermissions{}).Error; err != nil {
		respx.Alert(c, "清除旧授权错误，请重试")
		return
	}

	// 添加新授权
	for _, policy := range policies {
		newPermission := model_zh_kernel.ConsolePermissions{
			Entity:   req.Entity,
			EntityID: req.EntityId,
			PolicyID: policy.ID,
		}
		if err := conn.Tx.Save(&newPermission).Error; err != nil {
			respx.Alert(c, "保存授权错误，请重试")
			return
		}
	}

	conn.Commit()

	respx.Success(c, nil, nil)
}
